import 'dart:async';
import 'dart:convert';
import 'dart:ui';

import 'package:chewie/chewie.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_syt/api/api.dart';
import 'package:flutter_syt/application.dart';
import 'package:flutter_syt/datas/message_list_model.dart';
import 'package:flutter_syt/datas/message_model.dart';
import 'package:flutter_syt/datas/upload_data_model.dart';
import 'package:flutter_syt/datas/user_info.dart';
import 'package:flutter_syt/domain/mine/service/provider_unread_msg.dart';
import 'package:flutter_syt/domain/mine/service/widget/chat_scroll_behavior.dart';
import 'package:flutter_syt/domain/mine/service/widget/chat_scroll_physics.dart';
import 'package:flutter_syt/domain/mine/service/widget/service_messages_input.dart';
import 'package:flutter_syt/domain/mine/service/widget/service_messages_view.dart';
import 'package:flutter_syt/domain/widgets/common_dialog.dart';
import 'package:flutter_syt/domain/widgets/custom_dialog.dart';
import 'package:flutter_syt/domain/widgets/network_load_image.dart';
import 'package:flutter_syt/domain/widgets/photo_views_more_screen.dart';
import 'package:flutter_syt/generated/l10n.dart';
import 'package:flutter_syt/global_common.dart';
import 'package:flutter_syt/global_easy_loading.dart';
import 'package:flutter_syt/theme/theme_color.dart';
import 'package:flutter_syt/utils/click_utils.dart';
import 'package:flutter_syt/utils/fade_route.dart';
import 'package:flutter_syt/utils/image_picker_helper.dart';
import 'package:flutter_syt/utils/utils_dlog.dart';
import 'package:flutter_syt/utils/web_socket_mall.dart';
import 'package:flutter_syt/utils/web_socket_utility.dart';
import 'package:flutter_syt/widgets/normal_table.dart';
import 'package:flutter_syt/widgets/web_detail.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:video_compress/video_compress.dart';
import 'package:video_player/video_player.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:yyy_route_annotation/yyy_route_annotation.dart';

@RoutePage(name: "service_socket")
class ServiceSocket extends StatefulWidget {
  static bool isOpen = false;
  // bool isClickOpenWeb;
  final String source;
  final GoodsInfoContentModel? infoContentModel;
  ServiceSocket(
    this.source, {
    this.infoContentModel,
    // this.isClickOpenWeb = true
  });
  @override
  ServiceSocketState createState() => ServiceSocketState();
}

class ServiceSocketState extends State<ServiceSocket>
    with MsgItemDelegate, WebSocketDelegate, WidgetsBindingObserver {
  // List<MessageModel> messagesDataSource = [];
  TextEditingController _controller = TextEditingController();
  MessageListModel _listModel = MessageListModel();
  // RefreshController _refreshController = RefreshController();

  VideoPlayerController? _videoPlayerController;
  ChewieController? _chewieController;
  ScrollController _scrollController = ScrollController();

  late StreamSubscription _subscription;
  bool keyVisible = false;
  // GoodsInfoModel? _goodsInfoModel;
  bool showGoods = false;
  RefreshStatus _refreshStatus = RefreshStatus.idle;
  // bool _enablePullUp = false;
  GlobalKey _singViewKey = GlobalKey();
  GlobalKey _expViewKey = GlobalKey();
  double emptyHeight = 0.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(
            S.of(context).service_official,
          ),
        ),
        body: GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: ClickUtils.debounce(() {
              DLog(UserInfo.me.id);
              FocusScope.of(context).requestFocus(FocusNode());
            }),
            child: SafeArea(
              bottom: false,
              child: Container(
                child: Column(
                  children: [
                    Expanded(
                        key: _expViewKey,
                        child: ScrollConfiguration(
                            behavior: ChatScrollBehavior(),
                            child: Align(
                              // 此处为关键代码
                              alignment: Alignment.topCenter,
                              child: ListView.builder(
                                key: _singViewKey,
                                controller: _scrollController,
                                // addAutomaticKeepAlives: false,
                                // physics: BouncingScrollPhysics(),
                                shrinkWrap: true,
                                reverse: true,
                                // physics: AlwaysScrollableScrollPhysics(),
                                // addAutomaticKeepAlives: false,
                                padding: EdgeInsets.only(
                                    bottom: ScreenUtil().setWidth(10),
                                    left: 15.w,
                                    right: 15.w),
                                itemCount:
                                    (_listModel.messages ?? []).length + 2,
                                physics: ChatScrollPhysics(
                                    parent: AlwaysScrollableScrollPhysics()),
                                itemBuilder:
                                    (BuildContext itemContext, int index) {
                                  if (index ==
                                      (_listModel.messages ?? []).length + 1) {
                                    if ((_listModel.messages ?? []).length <
                                        6) {
                                      return SizedBox();
                                    }
                                    return loadingView();
                                  }
                                  if (index == 0) {
                                    return SizedBox(
                                      // color: Colors.amberAccent,
                                      height: emptyHeight,
                                    );
                                  }
                                  MessageModel messageModel =
                                      _listModel.messages![index - 1];
                                  return ServiceMessagesView(
                                    delegate: this,
                                    messageModel: messageModel,
                                    chewieController: messageModel.isPlay
                                        ? _chewieController
                                        : null,
                                  );
                                },
                              ),
                            ))),
                    (showGoods &&
                            widget.infoContentModel?.id != null &&
                            (widget.infoContentModel?.id ?? '').isNotEmpty)
                        ? _buildSendGoodsInfoView()
                        : Container(
                            height: 0.1,
                          ),
                    ServideMessagesInput(
                      controller: _controller,
                      sendMsgBlock: (msg) {
                        sendTextMsg(msg);
                      },
                      clickPhoto: () {
                        _pickImage();
                      },
                    )
                  ],
                ),
              ),
            )));
  }

  Widget _buildSendGoodsInfoView() {
    return Container(
      padding: EdgeInsets.symmetric(vertical: 12.w, horizontal: 15.w),
      color: Color(0xFFF7F7F7),
      height: 108.w,
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Stack(
          children: [
            Positioned.fill(
                child: Container(
              padding: EdgeInsets.all(12.w),
              child: Row(
                children: [
                  ClipRRect(
                    borderRadius: BorderRadius.circular(4),
                    child: NetworkLoadImage.loadNetworkImage(
                        widget.infoContentModel?.picUrl,
                        width: 60.w,
                        height: 60.w),
                  ),
                  SizedBox(
                    width: 10.w,
                  ),
                  Expanded(
                      child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Container(
                          alignment: Alignment.centerLeft,
                          constraints: BoxConstraints(maxWidth: 212.w),
                          child: Text(
                            widget.infoContentModel?.name ?? '',
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                            style: TextStyle(fontSize: 16),
                          )),
                      Row(
                        crossAxisAlignment: CrossAxisAlignment.end,
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          RichText(
                            textAlign: TextAlign.left,
                            text: TextSpan(
                              children: widget.infoContentModel?.type == '2'
                                  ? [
                                      TextSpan(
                                        text:
                                            "${widget.infoContentModel?.price}",
                                        style: (TextStyle(
                                          fontWeight: FontWeight.w500,
                                          fontSize: 16,
                                          color: Color(0xFFFF5700),
                                        )),
                                      ),
                                      TextSpan(
                                        text: S.current.service_point,
                                        style: (TextStyle(
                                          fontWeight: FontWeight.w500,
                                          fontSize: 12,
                                          color: Color(0xFFFF5700),
                                        )),
                                      ),
                                    ]
                                  : [
                                      TextSpan(
                                        text: "￥",
                                        style: (TextStyle(
                                          fontWeight: FontWeight.w500,
                                          fontSize: 12,
                                          color: Color(0xFFFF5700),
                                        )),
                                      ),
                                      TextSpan(
                                        text:
                                            "${widget.infoContentModel?.price}",
                                        style: (TextStyle(
                                          fontWeight: FontWeight.w500,
                                          fontSize: 16,
                                          color: Color(0xFFFF5700),
                                        )),
                                      ),
                                    ],
                            ),
                          ),
                          GestureDetector(
                              onTap: ClickUtils.debounce(() {
                                showGoods = false;
                                sendGoodsMsg(widget.infoContentModel!);
                              }),
                              child: Container(
                                height: 30.w,
                                decoration: BoxDecoration(
                                    color: ThemeColor.primaryColor,
                                    borderRadius: BorderRadius.circular(6)),
                                padding: EdgeInsets.symmetric(horizontal: 12.w),
                                child: Center(
                                  child: Text(
                                    S.current.service_sendGoods,
                                    style: TextStyle(fontSize: 14),
                                  ),
                                ),
                              ))
                        ],
                      )
                    ],
                  ))
                ],
              ),
            )),
            Positioned(
                right: 0,
                child: GestureDetector(
                    onTap: ClickUtils.debounce(() {
                      if (mounted) {
                        setState(() {
                          showGoods = false;
                        });
                      }
                    }),
                    child: Container(
                      width: 36,
                      height: 36,
                      child: Center(
                        child: Image.asset(
                            'assets/images/service_goods_close.png',
                            width: 12,
                            height: 12),
                      ),
                    )))
          ],
        ),
      ),
    );
  }

  Future sendTextMsg(String msg) async {
    MessageModel model =
        MessageModel(content: msg, type: 10, msgType: 1, source: widget.source);
// model.source = showGoods ? 'mall' : 'self';
    bool sendStatus = await (widget.source == 'self'
        ? WebSocketUtility.instance.sendMessage(model)
        : WebSocketMall.instance.sendMessage(model));
    model.status = sendStatus
        ? SendStatus.SendStatusSendDone
        : SendStatus.SendStatusSendFailed;

    model.direction = MessageDirection.SEND;
    _controller.text = '';
    _listModel.messages!.insert(0, model);
    if (mounted) {
      setState(() {});
    }
  }

  Future sendImageMsg(String pic) async {
    MessageModel model =
        MessageModel(picUrl: pic, type: 10, msgType: 2, source: widget.source);
    DLog(model.toJson());
    // model.source = showGoods ? 'mall' : 'self';
    bool sendStatus = await (widget.source == 'self'
        ? WebSocketUtility.instance.sendMessage(model)
        : WebSocketMall.instance.sendMessage(model));

    model.status = sendStatus
        ? SendStatus.SendStatusSendDone
        : SendStatus.SendStatusSendFailed;
    model.direction = MessageDirection.SEND;
    _listModel.messages!.insert(0, model);
    // _listModel.messages?.add(model);

    // if (FocusScope.of(context).canRequestFocus) {
    //   FocusScope.of(context).requestFocus(FocusNode());
    // }
    if (mounted) {
      setState(() {});
    }
    calculateEmptyHeight();
    // _scrollController.animateTo(0,
    // duration: Duration(milliseconds: 300), curve: Curves.easeIn);
  }

  Future sendGoodsMsg(GoodsInfoContentModel goodsModel) async {
    if (widget.infoContentModel != null) {
      MessageModel model = MessageModel(
          content: jsonEncode(widget.infoContentModel!.toJson()),
          type: 10,
          msgType: 10,
          source: widget.source);
      bool sendStatus = await (widget.source == 'self'
          ? WebSocketUtility.instance.sendMessage(model)
          : WebSocketMall.instance.sendMessage(model));

      model.status = sendStatus
          ? SendStatus.SendStatusSendDone
          : SendStatus.SendStatusSendFailed;
      model.direction = MessageDirection.SEND;
      // model.source = showGoods ? 'mall' : 'self';
      _listModel.messages!.insert(0, model);
      // _listModel.messages?.add(model);
      // if (FocusScope.of(context).canRequestFocus) {
      //   FocusScope.of(context).requestFocus(FocusNode());
      // }
      if (mounted) {
        setState(() {});
      }
      calculateEmptyHeight();
      // _scrollController.animateTo(0,
      // duration: Duration(milliseconds: 300), curve: Curves.easeIn);
    }
  }

  Future sendVideoMsg(String pic) async {
    MessageModel model =
        MessageModel(picUrl: pic, type: 10, msgType: 4, source: widget.source);
    DLog(model.toJson());

    bool sendStatus = await (widget.source == 'self'
        ? WebSocketUtility.instance.sendMessage(model)
        : WebSocketMall.instance.sendMessage(model));
    model.status = sendStatus
        ? SendStatus.SendStatusSendDone
        : SendStatus.SendStatusSendFailed;
    model.direction = MessageDirection.SEND;
    model.createTime = DateTime.now().millisecondsSinceEpoch;
    _listModel.messages!.insert(0, model);
    // model.source = showGoods ? 'mall' : 'self';
    // _listModel.messages?.add(model);
    // if (FocusScope.of(context).canRequestFocus) {
    //   FocusScope.of(context).requestFocus(FocusNode());
    // }
    await getVideoThumbn([model], 0);
    if (mounted) {
      setState(() {});
    }
    calculateEmptyHeight();
    // _scrollController.animateTo(0,
    // duration: Duration(milliseconds: 300), curve: Curves.easeIn);
  }

  _pickImage() async {
    int index = await DialogHelper.showBottom(context);
    if (index == 2) {
      return;
    }
    await Future.delayed(Duration(milliseconds: 100)); // Add this line
    ChooseImageData data = await ImageHelper.pickMutableImage(context,
        maxCount: 3, source: index);
    if ((data.entities ?? []).isNotEmpty) {
      await loading(() async {
        await _uploadImageOrVideo(data, 0);
      }, text: S.of(context).submitting);
    }
  }

  Future _uploadImageOrVideo(ChooseImageData data, int index) async {
    if (index < (data.entities ?? []).length) {
      String filename =
          "${UserInfo.me.id}_${DateTime.now().microsecondsSinceEpoch}.${data.files[index].path.split('.').last}";
      UploadDataModel uploadDataModel =
          await API.shared.common.uploadData(filename);
      DLog(uploadDataModel.toJson());

      String filePath = data.files[index].path;
      if (data.entities![index].type == AssetType.video) {
        MediaInfo? mediaInfo = await VideoCompress.compressVideo(
          data.files[index].path,
          quality: VideoQuality.Res640x480Quality,
          deleteOrigin: false, // It's false by default
        );
        filePath = (mediaInfo != null && mediaInfo.path != null)
            ? mediaInfo.path!
            : data.files[index].path;
      }

      var formData = FormData.fromMap({
        'key': '${uploadDataModel.dir}${uploadDataModel.saveName}',
        'success_action_status': 200,
        'OSSAccessKeyId': uploadDataModel.accessid,
        'policy': uploadDataModel.policy,
        'Signature': uploadDataModel.signature,
        // 'Content-Type': 'image/jpeg',
        'contentType': 'multipart/form-data',
        'file': await MultipartFile.fromFile(
          filePath,
        )
      });

      BaseOptions options = new BaseOptions();
      options.responseType = ResponseType.plain;
      Dio dio = new Dio(options);
      // try {
      Response response = await dio.post(
        uploadDataModel.host ?? '',
        data: formData,
        onSendProgress: (count, total) {
          DLog("$count + " " + $total");
        },
      );
      DLog(response.data);
      if (response.statusCode == 200) {
        if (data.entities![index].type == AssetType.video) {
          await sendVideoMsg(
              '${uploadDataModel.host}/${uploadDataModel.dir}${uploadDataModel.saveName}');
        } else {
          await sendImageMsg(
              '${uploadDataModel.host}/${uploadDataModel.dir}${uploadDataModel.saveName}');
        }
      }
      index++;
      _uploadImageOrVideo(data, index);
    }
  }

  Future getHistoryMsg({int? id, bool isJump = false}) async {
    // _refreshStatus = RefreshStatus.refreshing;
    if (_refreshStatus == RefreshStatus.idle ||
        _refreshStatus == RefreshStatus.failed) {
      _refreshStatus = RefreshStatus.refreshing;
      try {
        MessageListModel messageListModel = await API.shared.user
            .getServiceMsg(id ?? _listModel.lastId ?? 0, source: widget.source);
        // _refreshController.refreshCompleted();
        // _refreshStatus = RefreshStatus.completed;
        if (_listModel.lastId == 0) {
          _listModel = messageListModel;
          // _listModel.messages = messageListModel.messages?.reversed.toList();
          //  _listModel.messages = messageListModel.messages;
        } else {
          // messageListModel.messages?.reversed.toList();
          _listModel.lastId = messageListModel.lastId;
          (_listModel.messages ?? []).addAll(messageListModel.messages ?? []);
        }
        if ((_listModel.messages ?? []).length % 20 == 0 ||
            (_listModel.messages ?? []).isEmpty) {
          _refreshStatus = RefreshStatus.idle;
        } else {
          _refreshStatus = RefreshStatus.completed;
        }
        if (mounted) {
          setState(() {});
        }
        List<MessageModel> videoRows = [];
        _listModel.messages?.forEach((element) {
          if (element.msgType == 4) {
            videoRows.add(element);
          }
        });
        await getVideoThumbn(videoRows, 0);
      } catch (e) {
        _refreshStatus = RefreshStatus.failed;
      }
      if (mounted) {
        setState(() {});
      }
      calculateEmptyHeight();
    }
  }

  calculateEmptyHeight() async {
    await Future.delayed(
      Duration(milliseconds: 50),
    );
    double singHeight = _singViewKey.currentContext?.size?.height ?? 0;
    double expHeight = _expViewKey.currentContext?.size?.height ?? 0;
    if (expHeight - singHeight > 0) {
      if (mounted) {
        setState(() {
          emptyHeight = expHeight - singHeight;
        });
      }
    }

    // if (mounted) {
    //   setState(() {
    //     emptyHeight = _expViewKey.currentContext?.size?.height -
    //   });
    // }
    // emptyHeight
  }

  Future getVideoThumbn(List<MessageModel> rows, int index) async {
    if (index < rows.length) {
      rows[index].videoImagePath = await VideoThumbnail.thumbnailFile(
        video: rows[index].picUrl ?? '',
        imageFormat: ImageFormat.PNG,
        maxWidth: 240,
        quality: 25,
      );
      index = index + 1;
      await getVideoThumbn(rows, index);
    }
  }

  initDataSource() async {
    await getHistoryMsg(isJump: true);
    var data = await API.shared.user.getServiceUrl(widget.source);
    if (data != null && data is String) {
      if (widget.source == 'self') {
        WebSocketUtility.instance
            .initWebSocket(wsUrl: data, source: widget.source);
        if (appContext.isRestartService == true) {
          appContext.isRestartService = false;
        }
        ProviderUnReadMsg unReadProvider =
            Provider.of<ProviderUnReadMsg>(context, listen: false);
        unReadProvider.unReadNum = 0;
        if (WebSocketUtility.instance.getSocketStatus() ==
            SocketStatus.SocketStatusConnected) {
          try {
            Future.delayed(Duration(seconds: 1), () {
              WebSocketUtility.instance
                  .sendMessage(MessageModel(type: 22, source: widget.source));
            });
          } catch (e) {}
        }
      } else {
        WebSocketMall.instance
            .initWebSocket(wsUrl: data, source: widget.source);
        if (appContext.isRestartMallService == true) {
          appContext.isRestartMallService = false;
        }
        if (WebSocketMall.instance.getSocketStatus() ==
            SocketStatus.SocketStatusConnected) {
          try {
            Future.delayed(Duration(seconds: 1), () {
              WebSocketMall.instance
                  .sendMessage(MessageModel(type: 22, source: widget.source));
            });
          } catch (e) {}
        }
      }
    }
  }

  initVideo(MessageModel model) async {
    if (model.picUrl != null) {
      _videoPlayerController = VideoPlayerController.network(model.picUrl!);
      await Future.delayed(Duration.zero);
      await _videoPlayerController?.initialize();
      _chewieController = ChewieController(
          deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
          videoPlayerController: _videoPlayerController!,
          autoPlay: true,
          // fullScreenByDefault: true,
          allowFullScreen: true);

      _chewieController?.addListener(() {
        Future.delayed(Duration(milliseconds: 10), () {
          if (_chewieController?.isFullScreen == false) {
            for (var i = 0; i < (_listModel.messages ?? []).length; i++) {
              _listModel.messages![i].isPlay = false;
            }
            _videoPlayerController?.pause();
            if (mounted) {
              setState(() {});
            }
          }
        });
      });
      Future.delayed(Duration(milliseconds: 100), () {
        _chewieController?.enterFullScreen();
      });
      _videoPlayerController!.addListener(() {
        DLog(_chewieController?.isFullScreen);
      });

      for (var i = 0; i < (_listModel.messages ?? []).length; i++) {
        _listModel.messages![i].isPlay = _listModel.messages![i] == model;
      }
      if (mounted) {
        setState(() {});
      }
    }
  }

  Widget loadingView() {
    var txt = S().loading;
    if (_refreshStatus == RefreshStatus.failed) {
      txt = S().load_failed;
    } else if (_refreshStatus == RefreshStatus.canRefresh) {
      txt = S().release_to_refresh;
    } else if (_refreshStatus == RefreshStatus.idle) {
      txt = S().swipe_to_refresh;
    } else if (_refreshStatus == RefreshStatus.completed) {
      txt = S().no_more;
    } else if (_refreshStatus == RefreshStatus.refreshing) {
      txt = S().loading;
    }
    Widget headerWidget = commonRefreshStateWidget(txt, Colors.white);
    return Container(height: kHeight, child: headerWidget);
  }

//   void _getMoreData() async {
//   if (_refreshStatus == RefreshStatus.idle) {
//     _refreshStatus = RefreshStatus.refreshing;
//     // loadText = '加载中...';
//     List moreList = [];
//     var sentTime =
//         this._historyMessageList[_historyMessageList.length - 1].sentTime;
//     var list = await RongImSdk.getHistoryMessage(_groupId, sentTime, 20, 0);
//     if (list.length > 0) {
//       //去掉第一条,因为第一条已经显示
//       for (int i = 1; i < list.length; i++) {
//         moreList.add(list[i]);
//       }
//       if (moreList.length > 0) {
//         _loadStatus = LoadingStatus.STATUS_IDLE;
//         this._historyMessageList.addAll(moreList);
//       } else {
//         _loadStatus = LoadingStatus.STATUS_COMPLETED;
//         loadText = '已显示全部消息';
//       }
//     } else {
//       _loadStatus = LoadingStatus.STATUS_COMPLETED;
//       loadText = '已显示全部消息';
//     }
//     setState(() {});
//   }
// }

  // Future getHistoryGoodsInfo(List<MessageModel> rows, int index) async {
  //   if (index < rows.length) {
  //     if ((rows[index].content ?? '').length > 0 &&
  //         jsonDecode(rows[index].content ?? '') is Map) {
  //       GoodsInfoContentModel model = GoodsInfoContentModel.fromJson(
  //           jsonDecode(rows[index].content ?? ''));
  //       await getGoodsInfo(
  //         model,
  //         needSet: false,
  //       );
  //     }

  //     // rows[index].videoImagePath = await VideoThumbnail.thumbnailFile(
  //     //   video: rows[index].picUrl ?? '',
  //     //   imageFormat: ImageFormat.PNG,
  //     //   maxWidth: 240,
  //     //   quality: 25,
  //     // );
  //     index = index + 1;
  //     await getHistoryGoodsInfo(rows, index);
  //   }

  //   // return;
  // }

  // Future getGoodsInfo(GoodsInfoContentModel model,
  //     {bool needSet = true}) async {
  //   GoodsInfoModel infoModel = (model.type == '2')
  //       ? (await API.shared.common.getGoodsIntegralDetail(
  //           model.appid ?? '', model.id ?? '', model.storeId ?? '0'))
  //       : (await API.shared.common.getGoodsDetail(
  //           model.appid ?? '', model.id ?? '', model.storeId ?? '0'));
  //   // if (infoModel != null) {
  //   GoodsInfoDataSource.goodsMap[model.id ?? ''] = infoModel;
  //   // }

  //   if (needSet) {
  //     _goodsInfoModel = infoModel;
  //     if (mounted) {
  //       setState(() {});
  //     }
  //   }
  // if (model.type == '2') {
  //   _goodsInfoModel = await API.shared.common.getGoodsIntegralDetail(
  //       model.appid ?? '', model.id ?? '', model.storeId ?? '0');
  //   if (_goodsInfoModel != null) {
  //     GoodsInfoDataSource.goodsMap[model.id ?? ''] = _goodsInfoModel;
  //   }
  //   if (needSet) {
  //     if (mounted) {
  //       setState(() {});
  //     }
  //   }
  //   // });
  // } else {
  //   _goodsInfoModel = await API.shared.common.getGoodsDetail(
  //       model.appid ?? '', model.id ?? '', model.storeId ?? '0');

  //   if (_goodsInfoModel != null) {
  //     GoodsInfoDataSource.goodsMap[model.id ?? ''] = _goodsInfoModel;
  //   }
  //   if (needSet) {
  //     if (mounted) {
  //       setState(() {});
  //     }
  //   }
  // }
  // }

  @override
  void initState() {
    super.initState();

    DLog(UserInfo.me.id);
    _listModel.lastId = 0;
    _listModel.messages = [];
    ServiceSocket.isOpen = true;
    if (widget.infoContentModel != null) {
      showGoods = true;
    }
    initDataSource();
    _subscription =
        KeyboardVisibilityController().onChange.listen((bool visible) {
      print('Keyboard visibility update. Is visible: $visible');
      if (emptyHeight > 0) {
        if (visible == true) {
          Future.delayed(Duration(milliseconds: 50), () {
            if (mounted) {
              setState(() {
                emptyHeight = 1;
              });
            }
          });
        } else {
          calculateEmptyHeight();
        }
      }
      // if (visible == true && emptyHeight > 0) {
      //   Future.delayed(Duration(milliseconds: 50), () {
      //     if (mounted) {
      //       setState(() {
      //         emptyHeight = 1;
      //       });
      //     }
      //   });
      // } else  if (){

      // }
      // if (keyVisible != visible) {
      //   keyVisible = visible;
      //   calculateEmptyHeight();
      // }
    });
    if (widget.source == 'self') {
      WebSocketUtility.instance.setWebSocketDelegate(this);
    } else {
      WebSocketMall.instance.setWebSocketDelegate(this);
    }

    WidgetsBinding.instance.addObserver(this);
    _scrollController.addListener(scrollListener);
  }

  void scrollListener() {
    if (_scrollController.position.pixels >=
        _scrollController.position.maxScrollExtent) {
      // _getMoreData();
      getHistoryMsg();
      // DLog('_getMoreData');
    }
  }

  @override
  void dispose() {
    super.dispose();
    _subscription.cancel();
    _scrollController.dispose();
    ServiceSocket.isOpen = false;
    _videoPlayerController?.dispose();
    _chewieController?.dispose();
    WidgetsBinding.instance.removeObserver(this);

    if (widget.source == 'self') {
      WebSocketUtility.instance
          .sendMessage(MessageModel(type: 21, source: widget.source));
      WebSocketUtility.instance.removeWebSocketDelegate();
    } else {
      WebSocketMall.instance
          .sendMessage(MessageModel(type: 21, source: widget.source));
      WebSocketMall.instance.removeWebSocketDelegate();
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // getHistoryMsg(id: 0);
    // if (widget.source == 'self') {
    //   if (state == AppLifecycleState.resumed &&
    //       WebSocketUtility.instance.getSocketStatus() ==
    //           SocketStatus.SocketStatusClosed) {
    //     getHistoryMsg();
    //   }
    // } else {
    //   if (state == AppLifecycleState.resumed &&
    //       WebSocketMall.instance.getSocketStatus() ==
    //           SocketStatus.SocketStatusClosed) {
    //     getHistoryMsg();
    //   }
    // }
  }

  @override
  void didUpdateWidget(ServiceSocket oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  @override
  void didTapMessageItem(MessageModel message) {
    if (message.msgType == 2) {
      Navigator.of(context).push(FadeRoute(
          page: PhotoViewMoreScreen(
        imageRows: [message.picUrl ?? ''],
      )
          // page: PhotoViewSimpleScreen(
          // imageProvider: NetworkImage(message.picUrl ?? '')
          ));
    } else if (message.msgType == 4) {
      if (message.isPlay) {
        return;
      }
      initVideo(message);
    } else if (message.msgType == 10) {
      try {
        GoodsInfoContentModel contentModel =
            GoodsInfoContentModel.fromJson(jsonDecode(message.content ?? ''));
        // if (widget.isClickOpenWeb) {
        var web = WebDetailPage(GlobalData.mallGoodsInfoMine(contentModel));
        // web.needLongpressSave = false;
        Navigator.of(context).push(MaterialPageRoute(
            builder: (context) => web,
            settings: RouteSettings(name: "mine_page", arguments: "")));
      } catch (e) {}
    }
  }

  @override
  void didTapFailMessageItem(MessageModel message) {
    showCommonDialog(
      context,
      DialogEntity(
        '',
        Container(
          child: Text(S.current.service_againSendMsg),
        ),
        () {
          Navigator.of(context).pop();
        },
        () async {
          Navigator.of(context).pop();
          _listModel.messages!.remove(message);
          if (mounted) {
            setState(() {});
          }
          await Future.delayed(Duration(milliseconds: 500));
          //  sendTextMsg(message.
          if (message.msgType == 1) {
            sendTextMsg(message.content ?? '');
          } else if (message.msgType == 2) {
            sendImageMsg(message.picUrl ?? '');
          }
        },
        cancelText: S.of(context).cancel,
        okText: S.of(context).service_againSend,
      ),
    );
  }

  @override
  void webSocketOnConnect(bool isConnect) {
    // TODO: implement webSocketOnConnect
    if (isConnect) {
      DLog('连接 成功');
    } else {
      DLog('连接 失败');
    }
  }

  @override
  void webSocketOnError(error) {
    // TODO: implement webSocketOnError
    DLog('webSocketOnError   $error');
  }

  @override
  void webSocketOnMessage(data) async {
    DLog('接收到消息$data');
    try {
      MessageModel model = MessageModel.fromJson(jsonDecode(data));
      model.direction = MessageDirection.RECEIVE;
      if (model.msgType == 4) {
        await getVideoThumbn([model], 0);
      }
      _listModel.messages!.insert(0, model);
      // _listModel.messages?.add(model);
      if (mounted) {
        setState(() {});
      }
      calculateEmptyHeight();
    } catch (e) {
      DLog(e);
    }
  }
}
